/**
 * Author:yuiop
 * Date:2022/10/20 10:29
 */
package com.devops.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.devops.admin.mapper.DOSProjectWebhookMapper;
import com.devops.admin.model.DOSProjectWebhook;
import com.devops.admin.model.DOSWebhookCustomInfo;
import com.devops.admin.model.Pagination;
import com.devops.admin.model.TableResult;
import com.devops.admin.po.DOSWebhookCustomInfoPo;
import com.devops.admin.po.DOSWebhookInfoPo;
import com.devops.admin.service.DOSProjectWebhookService;
import com.devops.admin.service.DOSWebhookCustomInfoService;
import com.devops.admin.util.Assert;
import com.devops.admin.util.WebhookUtil;
import com.devops.admin.vo.DOSPageVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DOSProjectWebhookServiceImpl extends ServiceImpl<DOSProjectWebhookMapper, DOSProjectWebhook> implements DOSProjectWebhookService {

    @Autowired
    private DOSWebhookCustomInfoService dosWebhookCustomInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveWebhook(DOSProjectWebhook webhook) {
        Assert.isTrue(webhook != null,"无法处理空的参数");
        Assert.isTrue(StrUtil.isNotBlank(webhook.getWebhook()),"webhook的url不能为空");
        Assert.isTrue(StrUtil.isNotBlank(webhook.getTitle()),"webhook的title不能为空");
        Assert.isTrue(webhook.getType() != null && webhook.getType() > 0,"webHook的type不能为空");
        long count;
        if (webhook.getType() == 2) {
            Assert.isTrue(webhook.getProjectId() != null && webhook.getProjectId() > 0, "项目id不能为空");
            count = count(Wrappers.<DOSProjectWebhook>lambdaQuery()
                    .eq(DOSProjectWebhook::getProjectId,webhook.getProjectId())
                    .eq(DOSProjectWebhook::getTitle,webhook.getTitle())
                    .eq(DOSProjectWebhook::getWebhook,webhook.getWebhook()));
        }else {
            Assert.isTrue(webhook.getSubType() != null && webhook.getSubType() >0,"webhook的subType不能为空");
            count = count(Wrappers.<DOSProjectWebhook>lambdaQuery()
                    .eq(DOSProjectWebhook::getTitle,webhook.getTitle())
                    .eq(DOSProjectWebhook::getWebhook,webhook.getWebhook()));
        }

        Assert.isTrue(count == 0,"不可重复绑定");
        // 刚创建的webhook默认是可用的
        if (webhook.getStatus() == null || webhook.getStatus() < 1){
            webhook.setStatus(1);
        }
        return save(webhook);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateWebhook(DOSProjectWebhook webhook) {
        Assert.isTrue(webhook != null,"无法处理空的参数");
        Assert.isTrue(webhook.getId() != null && webhook.getId() > 0,"id不能为空");
        return updateById(webhook);
    }

    @Override
    public TableResult<DOSWebhookInfoPo> getWebhookPage(DOSProjectWebhook webhook, DOSPageVo pageVo) {
        Assert.isTrue(webhook.getType() != null && webhook.getType() > 0,"webHook的type不能为空");
        Page<DOSWebhookInfoPo> page = new Page<>(pageVo.getPageNum(), pageVo.getPageSize());
        TableResult<DOSWebhookInfoPo> tableResult = new TableResult<>();
        // 分页查询webhook列表
        List<DOSWebhookInfoPo> webhooks = baseMapper.selectWebhookPage(webhook,page);
        if (CollectionUtil.isEmpty(webhooks)){
            return null;
        }
        List<Integer> webhookIds = webhooks.stream().map(DOSWebhookInfoPo::getId).collect(Collectors.toList());
        // 如果是子webhook不需要二级类型
        if (webhook.getType() == 2){
            webhooks.forEach(webhookResult -> webhookResult.setSubType(null));
        } else {
            List<DOSWebhookCustomInfoPo> webhookCustomInfos = dosWebhookCustomInfoService.getListByWebhookIds(webhookIds);
            if (CollectionUtil.isNotEmpty(webhookCustomInfos)){
                webhooks.forEach(webhookResult -> {
                    for (DOSWebhookCustomInfoPo webhookCustomInfo : webhookCustomInfos) {
                        if (webhookCustomInfo.getWebhookId().intValue() == webhookResult.getId()){
                            // 如果模板为空，则需要给前端返回一个json模板
                            if (StrUtil.isEmpty(webhookCustomInfo.getMsgTemplate())){
                                webhookCustomInfo.setMsgTemplate(getDefaultTemplate());
                            }
                            if (webhookCustomInfo.getSendType() == null || webhookCustomInfo.getSendType() < 1){
                                webhookCustomInfo.setSendType(1);
                            }
                            webhookResult.setWebhookCustomInfo(webhookCustomInfo);
                        }
                    }
                });
            }
            // 处理
            webhooks.forEach(webhookResult -> {
                if (webhookResult.getSubType() == 1){
                    if (webhookResult.getWebhookCustomInfo() != null){
                        DOSWebhookCustomInfoPo webhookCustomInfo = webhookResult.getWebhookCustomInfo();
                        if (StrUtil.isEmpty(webhookCustomInfo.getMsgTemplate())){
                            webhookCustomInfo.setMsgTemplate(getDefaultTemplate());
                            if (webhookCustomInfo.getSendType() == null || webhookCustomInfo.getSendType() < 1){
                                webhookCustomInfo.setSendType(1);
                            }
                            webhookResult.setWebhookCustomInfo(webhookCustomInfo);
                        }
                    } else {
                        DOSWebhookCustomInfoPo webhookCustomInfo = DOSWebhookCustomInfoPo.builder()
                                .msgTemplate(getDefaultTemplate())
                                .sendType(1)
                                .build();
                        webhookResult.setWebhookCustomInfo(webhookCustomInfo);
                    }
                }
            });
        }
        Pagination p = Pagination.builder().pageNum(page.getCurrent()).pageSize(page.getSize()).total(page.getTotal()).build();
        tableResult.setPagination(p);
        tableResult.setList(webhooks);

        return tableResult;
    }

    @Override
    public String testWebhook(DOSProjectWebhook webhook){
        String url;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            url = WebhookUtil.dealWebHook(webhook.getWebhook(),webhook.getSecret());
        } catch (Exception e) {
            e.printStackTrace();
            return "webhook连接异常";
        }

        JSONObject mdJson = new JSONObject();
        mdJson.put("title","测试信息");
        mdJson.put("text"," **测试webhook,测试时间："+format.format(new Date()) + "**");

        JSONObject msgJson = new JSONObject();
        msgJson.put("msgtype","markdown");
        msgJson.put("markdown",mdJson);

        HttpResponse response = HttpRequest.post(url).body(msgJson.toJSONString()
                , "application/json;charset=UTF-8").execute();
        if (response != null) {
            if (response.getStatus() == 200) {
                return "webhook连接正常";
            }
        }
        return "webhook连接异常";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteWebhookById(Integer id) {
        DOSWebhookCustomInfo customInfo = dosWebhookCustomInfoService.getOne(Wrappers.<DOSWebhookCustomInfo>lambdaQuery()
                .eq(DOSWebhookCustomInfo::getWebhookId, id));
        if (customInfo != null && customInfo.getId() != null) {
            dosWebhookCustomInfoService.removeById(customInfo.getId());
        }

        return this.removeById(id);
    }

    @Override
    public List<DOSWebhookCustomInfoPo> getWebhookAndCustom(Integer projectId,Integer clusterId) {
        List<DOSWebhookCustomInfoPo> infoPos = baseMapper.selectWebhookAndCustomList(projectId);
        Map<Integer, List<DOSWebhookCustomInfoPo>> listMap = infoPos.stream().collect(Collectors.groupingBy(DOSWebhookCustomInfoPo::getType));
        List<DOSWebhookCustomInfoPo> infoPoList;
        if (CollectionUtil.isNotEmpty(listMap.get(0))){
            infoPoList = listMap.get(0);
        } else {
            infoPoList = new ArrayList<>();
        }
        if (CollectionUtil.isNotEmpty(listMap.get(1)) && clusterId != null && clusterId > 0){
            List<DOSWebhookCustomInfoPo> customInfoPos = listMap.get(1);
            for (DOSWebhookCustomInfoPo customInfoPo : customInfoPos) {
                if (customInfoPo.getClusterIds().contains(String.valueOf(clusterId))){
                    infoPoList.add(customInfoPo);
                }
            }
        }
        return infoPoList;
    }

    /**
     * @Author heyabo
     * @Description webhook发送消息的默认模板
     * @Date 10:37 2022/12/1
     * @Param []
     * @return java.lang.String
     **/
    private String getDefaultTemplate() {
        String singleLineStr = "**TYPE**:" + "#{type}" +
                "  **REASON**:" + "#{reason}" +
                "  **集群**:" + "#{cluster}" +
                "  **命名空间**:" + "#{namespace}" +
                "  **KIND**:" + "#{kind}" +
                "  **NAME**:" + "#{name}" +
                "  **Message**:" + "#{message}" +
                "  **EventTime**:" + "#{eventTime}";
        cn.hutool.json.JSONObject msgJson = new cn.hutool.json.JSONObject();
        //md格式
        cn.hutool.json.JSONObject mdJson = new cn.hutool.json.JSONObject();
        mdJson.set("title", "#{title}");
        mdJson.set("text",singleLineStr);
        msgJson.set("msgtype","markdown");
        msgJson.set("markdown",mdJson);
        return msgJson.toString();
    }

}
